#include "cmsis_os.h"
#include "tos_task.h"
#include "tos_event.h"
#include <unistd.h>

#define TASK_LISTENER_STACK_SIZE      512
#define TASK_TRIGGER_STACK_SIZE       512

k_stack_t stack_listener_task1[TASK_LISTENER_STACK_SIZE];
k_stack_t stack_listener_task2[TASK_LISTENER_STACK_SIZE];
k_stack_t stack_listener_task3[TASK_LISTENER_STACK_SIZE];
k_stack_t stack_listener_task4[TASK_LISTENER_STACK_SIZE];
k_stack_t stack_trigger_task[TASK_TRIGGER_STACK_SIZE];


k_task_t task_listener1;
k_task_t task_listener2;
k_task_t task_listener3;
k_task_t task_listener4;
k_task_t task_trigger;

extern void listener_task1(void *arg);
extern void listener_task2(void *arg);
extern void listener_task3(void *arg);
extern void listener_task4(void *arg);
extern void trigger_task(void *arg);


const k_event_flag_t event_number_1     =  (k_event_flag_t)(1 << 0);
const k_event_flag_t event_number_2     =  (k_event_flag_t)(1 << 1);
const k_event_flag_t event_number_3     =  (k_event_flag_t)(1 << 2);
const k_event_flag_t event_number_4     =  (k_event_flag_t)(1 << 3);

k_event_t event;

void listener_task1(void *arg)
{
    k_event_flag_t flag_match;
    k_err_t err;

    while (K_TRUE) {
        err = tos_event_pend(&event, event_number_1,
                                &flag_match, TOS_TIME_FOREVER, TOS_OPT_EVENT_PEND_ALL | TOS_OPT_EVENT_PEND_CLR);
        if (err == K_ERR_NONE) {
            printf("number 1 has been pressed:\n");
        }
    }
}


void listener_task2(void *arg)
{
    k_event_flag_t flag_match;
    k_err_t err;

    while (K_TRUE) {
        err = tos_event_pend(&event, event_number_2,
                                &flag_match, TOS_TIME_FOREVER, TOS_OPT_EVENT_PEND_ALL | TOS_OPT_EVENT_PEND_CLR);
        if (err == K_ERR_NONE) {
            printf("number 2 has been pressed:\n");
        }
    }
}

void listener_task3(void *arg)
{
    k_event_flag_t flag_match;
    k_err_t err;

    while (K_TRUE) {
        err = tos_event_pend(&event, event_number_3,
                                &flag_match, TOS_TIME_FOREVER, TOS_OPT_EVENT_PEND_ALL | TOS_OPT_EVENT_PEND_CLR);
        if (err == K_ERR_NONE) {
            printf("number 3 has been pressed:\n");
        }
    }
}

void listener_task4(void *arg)
{
    k_event_flag_t flag_match;
    k_err_t err;

    while (K_TRUE) {
        err = tos_event_pend(&event, event_number_4,
                                &flag_match, TOS_TIME_FOREVER, TOS_OPT_EVENT_PEND_ALL | TOS_OPT_EVENT_PEND_CLR);
        if (err == K_ERR_NONE) {
            printf("number 4 has been pressed:\n");
        }
    }
}

void trigger_task(void *arg)
{
    int i = 1;

    while (K_TRUE) {
        scanf("%d", &i);
        switch (i)
        {
            case 1:
                tos_event_post(&event, event_number_1);
                break;
            case 2:
                tos_event_post(&event, event_number_2);
                break;
            case 3:
                tos_event_post(&event, event_number_3);
                break;
            case 4:
                tos_event_post(&event, event_number_4);
                break;
            default:
                break;
        }
        tos_task_delay(1000);
    }
}


int main(void)
{
    osKernelInitialize(); //TOS Tiny kernel initialize
    tos_event_create(&event, (k_event_flag_t)0u);
    (void)tos_task_create(&task_listener1, "listener1", listener_task1, NULL,
                            3, stack_listener_task1, TASK_LISTENER_STACK_SIZE, 0);
    (void)tos_task_create(&task_listener2, "listener2", listener_task2, NULL,
                            4, stack_listener_task2, TASK_LISTENER_STACK_SIZE, 0);
    (void)tos_task_create(&task_listener3, "listener3", listener_task3, NULL,
                            4, stack_listener_task3, TASK_LISTENER_STACK_SIZE, 0);
    (void)tos_task_create(&task_listener4, "listener4", listener_task4, NULL,
                            4, stack_listener_task4, TASK_LISTENER_STACK_SIZE, 0);
    (void)tos_task_create(&task_trigger, "trigger", trigger_task, NULL,
                            4, stack_trigger_task, TASK_TRIGGER_STACK_SIZE, 0);
    osKernelStart(); //Start TOS Tiny

    //退出的时候释放资源
}
